package edu.pku.sei.autounit.reflect.java;

import java.lang.reflect.TypeVariable;

import edu.pku.sei.autounit.annotation.Context;
import edu.pku.sei.autounit.reflect.AbstractMethod;
import edu.pku.sei.autounit.reflect.Class;
import edu.pku.sei.autounit.reflect.Constructor;
import edu.pku.sei.autounit.reflect.Type;
import edu.pku.sei.autounit.reflect.TypeParameter;

public class JavaConstructor extends AbstractMethod implements Constructor{

	private java.lang.reflect.Constructor<?> javaConstructor;
	private Type []parameters;
	private TypeFactory factory;
	
	protected JavaConstructor(Class c,java.lang.reflect.Constructor<?> javaConstructor,TypeFactory factory) {
		super(javaConstructor.getModifiers(),c,c.getFullName());
		this.javaConstructor = javaConstructor;
		this.factory = factory;
		
		Context context = javaConstructor.getAnnotation(Context.class);
		Type [] contexts = null;
		if(context != null){
			java.lang.Class<?>[] cs= context.value();
			contexts = new Type[cs.length];
			for(int i=0;i<cs.length;i++)
				contexts[i] = factory.getType(cs[i], this);
		}
		else
			contexts = new Type[0];
		
		TypeVariable<?> [] tps = javaConstructor.getTypeParameters();
		typeParameters = new TypeParameter[tps.length];
		for(int i =0 ;i<tps.length;i++){
			typeParameters[i] = new JavaTypeParameter(tps[i].getName());
			if(i<contexts.length)
				typeParameters[i].setContext(contexts[i]);
			
			java.lang.reflect.Type []tt = tps[i].getBounds();
			Type [] bs = new Type[tt.length];
			for(int j = 0; j<tt.length; j++)
				bs[j] = factory.getType(tt[j],this);
			typeParameters[i].setBounds(bs);
		}
	}

	
	public Type[] getParameters() {
		if(parameters == null){
			java.lang.reflect.Type []tt = javaConstructor.getGenericParameterTypes();
			parameters = new Type[tt.length];
			for(int i=0;i<tt.length;i++){
				parameters[i] = factory.getType(tt[i],this);
			}
		}
		return parameters;
	}

	
	public String getSource() {
		return null;
	}
	
	
	public boolean hasException() {
		return javaConstructor.getExceptionTypes().length!=0;
	}

	
	public String[] getFilters() {
		return null;
	}

	
	public Type getReturnType() {
		return null;
	}

	
	public java.lang.Class<?> getStrategy() {
		return null;
	}
}
